package org.vacoor.xqq.core.bean;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.vacoor.xqq.core.util.ImageResources;

import javax.swing.*;
import java.io.IOException;

/**
 * 用户状态
 * <p/>
 * User: Vacoor
 */
@JsonDeserialize(using = Status.StatusIgnoreCaseDeserializer.class)
public enum Status {
    ONLINE(10, "online", "我在线上", getIcon("online.png")),
    OFFLINE(20, "offline", "离线", getIcon("offline.png")),
    AWAY(30, "away", "离开", getIcon("away.png")),
    HIDDEN(40, "hidden", "隐身", getIcon("invisible.png")),
    BUSY(50, "busy", "忙碌", getIcon("busy.png")),
    CALLME(60, "callme", "Q我吧", getIcon("qme.png")),
    SILENT(70, "silent", "请勿打扰", getIcon("mute.png"));

    private static final String ICON_DIR = "images/status";

    private final int code;
    private final String name;
    private final String desc;
    private final Icon icon;

    Status(int code, String name, String desc, Icon icon) {
        this.code = code;
        this.name = name;
        this.desc = desc;
        this.icon = icon;
    }

    public int getCode() {
        return this.code;
    }

    public String getName() {
        return this.name;
    }

    public String getDesc() {
        return this.desc;
    }

    public Icon getIcon() {
        return this.icon;
    }

    private static Icon getIcon(String name) {
        return ImageResources.getIcon(ICON_DIR + "/" + name);
    }

    /**
     * 从字符串转换, 如果无法转换返回 null
     */
    public static Status fromString(String status) {
        try {
            return valueOf(status.toUpperCase());
        } catch (RuntimeException e) {
            return null;
        }
    }

    public static Status fromCode(int code) {
        for (Status s : Status.values()) {
            if (s.getCode() == code) {
                return s;
            }
        }
        return Status.OFFLINE;
    }

    /**
     * 是否是不可见状态
     */
    public static boolean isInvisible(Status status) {
        boolean offline = true;
        if (status != null && Status.HIDDEN != status && Status.OFFLINE != status) {
            offline = false;
        }
        return offline;
    }

    // -------------------------------------------------

    /**
     * 该反序列化器主要是为了解决将小写状态(eg: online) 转换为 Enum
     */
    static final class StatusIgnoreCaseDeserializer extends JsonDeserializer<Status> {

        @Override
        public Status deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            String text = jp.getText();

            if (text == null) {
                return Status.OFFLINE;
            }

            JsonToken curr = jp.getCurrentToken();
            if (curr == JsonToken.VALUE_STRING || curr == JsonToken.FIELD_NAME) {
                Status r = fromString(text);
                if (r == null) {
                    r = fromString(text.toUpperCase());
                }
                if (r == null) {
                    r = fromString(text.toLowerCase());
                }
                return r;
            }
            if (curr == JsonToken.VALUE_NUMBER_INT) {
                return Status.values()[jp.getIntValue()];
            }
            return null;
        }

        private Status fromString(String name) {
            try {
                return Status.valueOf(name);
            } catch (RuntimeException e) {
                return null;
            }
        }
    }
}
